//package SecureChat;
import java.io.*;
import java.net.*;
import SecureChat.ChatLib;
import java.util.*;
import SecureChat.Utilities;
import java.math.*;
import SecureChat.DHAuth;
//import SecureChat.*;

public class SCClient {
    public static void main(String[] args)
    {
	String password;
	Scanner sysin;
	boolean DEBUG;
	Socket s = null;
	String hostname = "127.0.0.1";
	int port = 1203;
	String clientID = "";
	String serverID = "";
	byte[] key = {0x00, 0x00, 0x00, 0x00,
		      0x00, 0x00, 0x00, 0x00,
		      0x00, 0x00, 0x00, 0x00,
		      0x00, 0x00, 0x00, 0x00};
	BigInteger G = null;
	OutputStream sOut;
	InputStream sIn;
	byte[] readBuffer;
	ChatLib c;

	//handle args
	if(args.length < 8){
	    System.out.println("This is the Client half of the secure chat program.");
	    System.out.println("usage: java SCClient -a address -p port -c clientID -s serverID [-d]");
	    System.out.println("  options");
	    System.out.println("\t-a\tIP Address of the server");
	    System.out.println("\t-p\tPort the server is listening on");
	    System.out.println("\t-c\tID to identify this client");
	    System.out.println("\t-s\tExpected server ID");
	    System.out.println("\t-d\tEnable debugging mode");
	    return;
	}
	for(int i = 0; i < args.length; ++i){
	    if(args[i].charAt(0) == '-'){
		
		switch (args[i].charAt(1)){
		case 'a':
		    if(i+1 <args.length && args[i+1].charAt(0) != '-'){
			hostname = args[i+1];
			++i;
			break;
		    }
		case 'p':
		    if(i+1 <args.length && args[i+1].charAt(0) != '-'){
			port = Integer.valueOf(args[i+1]);
			++i;
			break;
		    }
		case 'c':
		    if(i+1 <args.length && args[i+1].charAt(0) != '-'){
			clientID = args[i+1];
			++i;
			break;
		    }
		case 's':
		    if(i+1 <args.length && args[i+1].charAt(0) != '-'){
			serverID = args[i+1];
			++i;
			break;
		    }
		case 'd':
		    //Load debugging
		    Properties p = new Properties(System.getProperties());
		    p.setProperty("DEBUG", "true");
		    System.setProperties(p);
		    break;
		default:
		    System.out.println("Unrecognized or incomplete arguement");
		    System.exit(1);
		    break;
		}
	    }
	}
	//end handle args

	if(System.getProperty("DEBUG") != null){
	    DEBUG = true;
	    System.err.println("Debugging mode enabled");
	}
	else{
	    DEBUG = false;
	}

		
	System.out.println();
	System.out.println("Opening connection to " + hostname + " on port " + port + ". Client ID is " + clientID + " and the serverID is " + serverID );

	try{
	    s = new Socket(hostname, port);
	}
	catch(Exception e){
	    System.out.println("Error opening socket: " + e);
	    System.exit(1);
	}
	System.out.println("Client: Connected!");
	System.out.println("Enter in password for connection:");
	
	sysin = new Scanner(System.in);
	password = sysin.next();
	    
	try{
	    G = Utilities.GenG(password);
	}
	catch(Exception e){
	    System.out.println("Error generating G from password");
	    System.exit(1);
	}
	try{
	    sOut = s.getOutputStream();
	    sOut.write(clientID.getBytes());
	    sIn = s.getInputStream();
	    while(true){
		if(sIn.available() > 0){
		    readBuffer = new byte[sIn.available()];
		    sIn.read(readBuffer);
		    if(readBuffer[0] == 1 && readBuffer.length == 1){
			//Acknowledged
			break;
		    }
		    else{
			System.out.println("Unexpected value received from server.");
			System.out.println(readBuffer[0] + " " + readBuffer.length);
			System.exit(1);
		    }
		}
	    }
	}

	catch(Exception e){
	    System.out.println("Failure sending client ID to server: " + e);
	    System.exit(1);
	}
	
	key = DHAuth.Client(G, clientID, serverID, s);
	
	if(key != null){
	    System.out.println("Server authenticated.");
	    System.out.println("Type your message and press <return> to send. Type '/quit' to close the connection.");
	}
	else{
	    System.out.println("Server did not authenticate. Aborting");
	    System.exit(1);
	}
	
	c = new ChatLib(s, clientID, key);
    }
}
